//code by Sakihata

#include<stdio.h>
#include<stdlib.h>

void mapInit(char *dirtyMap);
void mapPrint(char *printMap);
void mapWrite(char mark,int writeNum,char *writeMap);
void logInit(int a[3][3]);
int reCheck(int a[3][3],int pos);
void logWrite(int num,int writeNum,int a[3][3]);
void logMapping(int writelog[3][3],char *writeMap);
void logPrint(int printlog[3][3]);
int faircheck(int checklog[3][3]);
int firCheck(int s1,int s2,int s3);
int winCheck(int log[3][3]);
void howPlay();
void enterGO();

int main()
{	
	char com;
	int step=0;
	static int log[3][3];
	char map[50];
	int whofir;
	int res=0;
	int grid=0;
	printf("Welcome to the FALab AI!\n");
	printf("Code by Sakihata at NEUQ\n\n");
	printf("Now please input your command or input 'h' to get help.\n\n\n");
	while(1)
	{
		printf("Ready for the command...\n");
		scanf("\n%c",&com);
		getchar();
		switch(com)
		{
			case 'h':printf("\'v\':to get the version information.\n\'p'\':to begin the chess game.\n\'w\':to help you understand how to play chess with this AI.\n\'q\':to quit this program\n\n");break;
			case 'v':printf("version:Alpha\nNow only get the basic function to play chess with you.\nEl Psy Congroo!\n\n");break;
			case 'p':step=1;mapInit(map);logInit(log);break;
			case 'w':howPlay();break;
			case 'q':exit(0);
			
			}
		while(step!=0)
		{
			if(step==1)
			{
				char litcom;	
				printf("you first?(y/n)\n");
				scanf("%c",&litcom);
				getchar();
				if(litcom=='y')
				{
					printf("OK,you first.\n");
					whofir=2;
				}
				else if(litcom=='n')
				{
					printf("OK,I first.\n");
					whofir=1;
				}
				else
				{
					printf("Error 002!");
				}
			}
			if(whofir==1)
			{
			/*	if(step==1)
				{
					logWrite(5,2,log);
				}
				else
				{*/
					
					grid=winCheck(log);
					//printf("%d\n",grid);
					while(reCheck(log,grid) || grid==0)
					{
						grid=(rand()+1)%10;
					}
					logWrite(grid,2,log);
			//	}
				
				step++;
			}
			if(whofir==2)
			{
				if(step==1)
				{
					mapPrint(map);
				}
				int grid;
				printf("Which grid do you want to choose?\n");
				scanf("%d",&grid);
				if(grid>0 && grid<10)
				{
					logWrite(grid,1,log);
				}
				else
				{
					printf("Error 003!");
				}
				
				step++;
			}
			logMapping(log,map);
			//logPrint(log);
			mapPrint(map);
			printf("\n\n");
			res=faircheck(log);
			switch(res)
			{
				case 1:printf("YOU WIN!\n\n");res=0;step=0;break;
				case 2:printf("YOU LOSE!\n\n");res=0;step=0;break;
				case 3:printf("DEUCE!\n\n");res=0;step=0;break;
			}
			if(whofir==1)
			{
				whofir=2;
			}
			else
			{
				whofir=1;
			}
		}
		
	}

}	
void mapInit(char *dirtyMap)
{
	char newMap[50]="+-+-+-+I I I I+-+-+-+I I I I+-+-+-+I I I I+-+-+-+";
	int i;
	for(i=0;i<49;i++)
	{
			*(dirtyMap+i)=newMap[i];
	}	
}

void mapPrint(char *printMap)
{
	int i;
	for(i=0;i<49;i++)
	{
		printf("%c",*(printMap+i));
		if((i+1)%7==0)
			printf("\n");
	}
}

void mapWrite(char mark,int writeNum,char *writeMap)
{
		switch(writeNum)
		{
			case 1:*(writeMap+8)=mark;break;
			case 2:*(writeMap+10)=mark;break;
			case 3:*(writeMap+12)=mark;break;
			case 4:*(writeMap+22)=mark;break;
			case 5:*(writeMap+24)=mark;break;
			case 6:*(writeMap+26)=mark;break;
			case 7:*(writeMap+36)=mark;break;
			case 8:*(writeMap+38)=mark;break;
			case 9:*(writeMap+40)=mark;break;
			default:printf("Error 001!");
		}
}

void logInit(int a[3][3])
{
	int i,j;
	for(i=0;i<3;i++)
		for(j=0;j<3;j++)
			a[i][j]=0;
}

int reCheck(int a[3][3],int pos)
{
	int i,j;
	int res;
	i=(pos-1)%3;
	j=(pos-1)/3;
	if(a[j][i]!=0)
	{
		res=1;
	}
	else
	{
		res=0;
	}
	return res;
}


void logWrite(int num,int writeNum,int a[3][3])
{	
	int (*writeLog)[3];
	writeLog=a;
	switch(num)
	{
		case 1:**writeLog=writeNum;break;
		case 2:*(*writeLog+1)=writeNum;break;
		case 3:*(*writeLog+2)=writeNum;break;
		case 4:*(*(writeLog+1))=writeNum;break;
		case 5:*(*(writeLog+1)+1)=writeNum;break;
		case 6:*(*(writeLog+1)+2)=writeNum;break;
		case 7:*(*(writeLog+2))=writeNum;break;
		case 8:*(*(writeLog+2)+1)=writeNum;break;
		case 9:*(*(writeLog+2)+2)=writeNum;break;
	}
}
void logMapping(int writelog[3][3],char *writeMap)
{
	int i,j;
	int pos;
	for(i=0;i<3;i++)
		for(j=0;j<3;j++)
			{
				pos=3*i+j+1;
				switch(writelog[i][j])
				{
					case 1:mapWrite('x',pos,writeMap);break;
					case 2:mapWrite('o',pos,writeMap);break;
					default:mapWrite(' ',pos,writeMap);
				}
			}
}

void logPrint(int printlog[3][3])
{
	int i,j;
	for(i=0;i<3;i++)
	{	
		for(j=0;j<3;j++)
		{	
			printf("%d",printlog[i][j]);
		}
	printf("\n");
	}
}
int faircheck(int checklog[3][3])
{
	int xrepNum=0,orepNum=0;
	int result=0;
	int i,j;
	int deucecheck=0;
	for(i=1;i<10;i++)
	{	
		if(checklog[(i-1)%3][(i-1)/3]==0)
		{
			break;
		}
		else
		{
			deucecheck++;
		}
	}
	if(deucecheck==9)
		return 3;
	for(i=0;i<3;i++)
	{	
		for(j=0;j<3;j++)
		{
			if(checklog[i][j]==1)
				xrepNum++;
			if(checklog[i][j]==2)
			    orepNum++;
			if(xrepNum>=3)
			{
				result=1;
				break;
			}
			if(orepNum>=3)
			{
				result=2;
				break;
			}
		}
		if(result!=0)
			break;
		xrepNum=0;
		orepNum=0;
	}
	if(result==0)
	{
		for(j=0;j<3;j++)
		{	
			for(i=0;i<3;i++)
			{
				if(checklog[i][j]==1)
					xrepNum++;
				if(checklog[i][j]==2)
					orepNum++;
				if(xrepNum>=3)
				{	
					result=1;
					break;
				}
				if(orepNum>=3)
				{
					result=2;
					break;
				}	
			}
			if(result!=0)
				break;
			xrepNum=0;
			orepNum=0;
		}
	}	
	if(result==0)
	{
			for(i=0;i<3;i++)
			{
				if(checklog[i][i]==1)
					xrepNum++;
				if(checklog[i][i]==2)
					orepNum++;
				if(xrepNum>=3)
				{	
					result=1;
					break;
				}
				if(orepNum>=3)
				{
					result=2;
				}
			}
		orepNum=0;
		xrepNum=0;
	}
	if(result==0)
	{
		for(i=0;i<3;i++)
		{
				if(checklog[i][2-i]==1)
					xrepNum++;
				if(checklog[i][2-i]==2)
					orepNum++;
				if(xrepNum>=3)
				{	
					result=1;
					break;
				}
				if(orepNum>=3)
				{
					result=2;
				}
		}
	}
	if(result==0)
	{
		for(i=0;i<3;i++)
			for(j=0;j<3;j++)
				if(checklog[i][j]==0)
					break;
	}
	return result;
}

int firCheck(int s1,int s2,int s3)
{
	int voidnum=0,voidpos=0;
	if(s1==0)
	{	
		voidnum++;
		voidpos=1;
	}
	if(s2==0)
	{
		voidnum++;
		voidpos=2;
	}
	if(s3==0)
	{
		voidnum++;
		voidpos=3;
	}
	if(voidnum!=3)
		return voidpos;
	else
		return 0;
}

int winCheck(int log[3][3])
{
	int point=0;
	int xnum=0,onum=0;
	int i,j;
	int voidpos=0,firpos=0,secpos=0;
	for(i=0;i<3;i++)
		if(firCheck(log[i][0],log[i][1],log[i][2]))
		{
			for(j=0;j<3;j++)
			{
				switch(log[i][j])
				{
					case 1:xnum++;break;
					case 2:onum++;break;
					case 0:voidpos=3*i+j+1;break;		
				}
				if(xnum==2 && point!=2)
				{
					point=1;
					firpos=voidpos;
				}
				if(onum==2)
				{
					point=2;
					secpos=voidpos;
				}
			}
		xnum=0;
		onum=0;
		}
	for(i=0;i<3;i++)
		if(firCheck(log[0][i],log[1][i],log[2][i]))
		{
			for(j=0;j<3;j++)
			{
				switch(log[j][i])
				{
					case 1:xnum++;break;
					case 2:onum++;break;
					case 0:voidpos=3*j+i+1;break;
				}
			}
			if(xnum==2 && point!=2)
			{
				point=1;
				firpos=voidpos;
			}
			if(onum==2)
			{
				point=2;
				secpos=voidpos;
			}
		xnum=0;
		onum=0;
		}
	if(firCheck(log[0][0],log[1][1],log[2][2]))
	{
		for(i=0;i<3;i++)
		{
			switch(log[i][i])
			{
				case 1:xnum++;break;
				case 2:onum++;break;
				case 0:voidpos=4*i+1;	
			}
		}
		if(xnum==2 && point!=2)
		{
			point=1;
			firpos=voidpos;
		}
		if(onum==2)
		{
			point=2;
			secpos=voidpos;
		}
	onum=0;
	xnum=0;
	}
	if(firCheck(log[0][2],log[1][1],log[2][0]))
	{
		for(i=0;i<3;i++)
		{
			switch(log[i][2-i])
			{
				case 1:xnum++;break;
				case 2:onum++;break;
				case 0:voidpos=3+2*i;
			}
		}
		if(xnum==2 && point!=2)
		{
			point=1;
			firpos=voidpos;
		}
		if(onum==2)
		{
			point=2;
			secpos=voidpos;
		}
	}
	//printf("%d\n",point);
	switch(point)
	{
		case 1:voidpos=firpos;break;
		case 2:voidpos=secpos;break;
		default:voidpos=5;
	}
	return voidpos;
}

void howPlay()
{
	int a;
	printf("So this is the first time you play the chess?\nLet's begin!\n");
	printf("+-+-+-+\nI I I I\n+-+-+-+\nI I I I\n+-+-+-+\nI I I I\n+-+-+-+\n");
	printf("Look at this,it is a chessboard.\n");
	printf("Each grid has its own number.\n");
	printf(" 1   2   3\n 4   5   6\n 7   8   9\n");
	printf("What you need to do is just to make three pointa on the same line.\n");
	enterGO();
	printf("Look at this.\n");
	printf("+-+-+-+\nIxIxI I\n+-+-+-+\nIoI I I\n+-+-+-+\nIoI I I\n+-+-+-+\n");
	enterGO();
	printf("if you are at the side of x.\n");
	printf("Which grid is the best choice?\n");
	enterGO();
	printf("Of cource!NO.3 grid.\n");
	printf("So what you need to do to get win is just input \'3\'\n");
	printf("Now,just input '3'\n");
	scanf("%d",&a);
	getchar();
	while(a!=3)
	{
		printf("Oops!You might input the wrong number.Let's try again!\n");
		scanf("%d",&a);
		getchar();
	}
	printf("Well done!Now you got three 'x' at the same line.\nSo you got the win!\n");
	enterGO();
	printf("+-+-+-+\nIxIxIxI\n+-+-+-+\nIoI I I\n+-+-+-+\nIoI I I\n+-+-+-+\n");
	printf("YOU WIN\n");
	printf("Now let's see another situation.");
	printf("If you are at the side of x,what you need to do to get win?\n");
	printf("Try it by yourself.\n");
	printf("+-+-+-+\nIxIxIoI\n+-+-+-+\nIoIxIoI\n+-+-+-+\nI I I I\n+-+-+-+\n\n");
	scanf("%d",&a);
	getchar();
	while(a!=8)
	{
		printf("Emm...Is it right?Let's try again!");
		scanf("%d",&a);
	}
	printf("Good job!So basically you have got to know how to play this chess.\n");
	enterGO();
	printf("I won't be merciful again.\n\n");
}
void enterGO()
{
	printf("\n\nPress Enter to keep this program going.\n\n");
	getchar();
}
